import time
from importlib import reload

from sqlalchemy import or_
from starlette.requests import Request
from model.db import reservoir_sensitivity, connect, TbUsers
from model.db.experiment_model import TbExperimentModell, TbExperimentModelInputParam, \
    TbExperimentModelOutputParam, TbExperimentPredictDatasets, TbExperimentModelTrainDatasets, \
    TbExperimentTestDatasets, TbExperimentModelsStructure, TbExperimentSOMModelsStructure
from model.db.mapper.experiment_mapper import get_core_param
from model.db.mapper.well_mapper import update_core_dataList
from model.db.well_model import TbRockCore, TbCoreParam, TbCoreData
from util import objs_to_dict, obj_to_dict


def add_model(name, type, des, user_id, sensitivity_type):
    try:
        newModel = TbExperimentModell(Model_Name=name, Model_Type=type, Model_Description=des, Creator_User=user_id,
                                      Sensitivity_Type=sensitivity_type)
        connect.projSession.add(newModel)
        connect.projSession.commit()
    except Exception as e:
        raise e

    # 该模型固定输出参数
    paramID = connect.projSession.query(TbCoreParam).filter_by(Sensitivity_Type=sensitivity_type).first().Parameter_ID
    modelParam = TbExperimentModelOutputParam(Model_ID=str(newModel.Model_ID), Parameter_ID=paramID)
    connect.projSession.add(modelParam)
    connect.projSession.commit()

    return newModel


def get_model_list(type, sensitive):
    if type == -1:
        models = connect.projSession.query(TbExperimentModell).filter_by(Sensitivity_Type=sensitive).all()
    else:
        models = connect.projSession.query(TbExperimentModell).filter_by(Model_Type=type,
                                                                         Sensitivity_Type=sensitive).all()
    return models


def get_model(model_id):
    model = connect.projSession.query(TbExperimentModell.Model_ID,
                                      TbExperimentModell.Model_Type, TbExperimentModell.Model_Description,
                                      TbExperimentModell.Model_Name, TbExperimentModell.Create_DateTime,
                                      TbExperimentModell.Update_DateTime, TbUsers.user_name).join(TbExperimentModell,
                                                                                                  TbExperimentModell.Creator_User == TbUsers.user_id).filter_by(
        Model_ID=model_id).first()
    return model


def update_model(model_id, model_name, model_description):
    model = connect.projSession.query(TbExperimentModell).filter_by(Model_ID=model_id).update(
        {
            'Model_Name': model_name,
            'Model_Description': model_description
        }
    )
    connect.projSession.commit()
    return model


def delete_model(model_id):
    model = connect.projSession.query(TbExperimentModell).filter_by(Model_ID=model_id).first()
    connect.projSession.delete(model)
    connect.projSession.commit()
    return


def get_model_paras(modle_id):
    input_paras = connect.projSession.query(TbCoreParam.Parameter_ID, TbCoreParam.Parameter_Ecode,
                                            TbCoreParam.Parameter_Name, TbCoreParam.Parameter_UOM_Name,
                                            TbCoreParam.Sensitivity_Type,
                                            TbExperimentModelInputParam.Parameter_Relation).join(
        TbExperimentModelInputParam,
        TbCoreParam.Parameter_ID == TbExperimentModelInputParam.Parameter_ID) \
        .filter(
        TbExperimentModelInputParam.Model_ID == modle_id) \
        .order_by(TbCoreParam.Parameter_ID) \
        .all()
    out_paras = connect.projSession.query(TbCoreParam).join(TbExperimentModelOutputParam,
                                                            TbCoreParam.Parameter_ID == TbExperimentModelOutputParam.Parameter_ID) \
        .filter(
        TbExperimentModelOutputParam.Model_ID == modle_id) \
        .order_by(TbCoreParam.Parameter_ID) \
        .all()
    return input_paras, out_paras


def get_multi_model_paras(modle_list):
    input_paras = connect.projSession.query(TbCoreParam).join(TbExperimentModelInputParam,
                                                              TbCoreParam.Parameter_ID == TbExperimentModelInputParam.Parameter_ID) \
        .filter(
        TbExperimentModelInputParam.Model_ID.in_(modle_list)).all()
    out_paras = connect.projSession.query(TbCoreParam).join(TbExperimentModelOutputParam,
                                                            TbCoreParam.Parameter_ID == TbExperimentModelOutputParam.Parameter_ID) \
        .filter(
        TbExperimentModelOutputParam.Model_ID.in_(modle_list)).all()
    return input_paras, out_paras


def update_model_inputParas(add, delete, update):
    try:
        if len(add) != 0:
            for item in add:
                core_param = get_core_param(item['Parameter_Ecode'])
                if core_param is not None:
                    new_input = TbExperimentModelInputParam(
                        Model_ID=item['Model_ID'],
                        Parameter_ID=core_param.Parameter_ID
                    )
                    connect.projSession.add(new_input)
                    item['Parameter_ID'] = core_param.Parameter_ID
                else:
                    new_core_parm = TbCoreParam(
                        Parameter_Ecode=item['Parameter_Ecode'],
                        Parameter_Name=item['Parameter_Name'],
                        Parameter_UOM_Name=item['Parameter_UOM_Name'],
                    )
                    connect.projSession.add(new_core_parm)
                    connect.projSession.commit()
                    new_input = TbExperimentModelInputParam(
                        Model_ID=item['Model_ID'],
                        Parameter_ID=new_core_parm.Parameter_ID
                    )
                    connect.projSession.add(new_input)
                    item['Parameter_ID'] = new_core_parm.Parameter_ID

        if len(delete) != 0:
            for item in delete:
                connect.projSession.query(TbExperimentModelInputParam) \
                    .filter_by(Model_ID=item['Model_ID'], Parameter_ID=item['Parameter_ID']) \
                    .delete(synchronize_session=False)
        if len(update) != 0:
            for item in update:
                connect.projSession.query(TbCoreParam).filter(TbCoreParam.Parameter_ID == item['Parameter_ID']) \
                    .update({'Parameter_Ecode': item['Parameter_Ecode'], 'Parameter_Name': item['Parameter_Name'],
                             'Parameter_UOM_Name': item['Parameter_UOM_Name']})
        connect.projSession.commit()
        connect.projSession.flush()
        return add
    except Exception as e:
        connect.projSession.rollback()
        raise e


def update_SOMmodel_ParasRelation(update):
    try:
        if len(update) != 0:
            for item in update:
                connect.projSession.query(TbExperimentModelInputParam).filter(
                    TbExperimentModelInputParam.Parameter_ID == item['Parameter_ID'],
                    TbExperimentModelInputParam.Model_ID == item['Model_ID']) \
                    .update({'Parameter_Relation': item['Parameter_Relation']})
        connect.projSession.commit()
        connect.projSession.flush()
    except Exception as e:
        connect.projSession.rollback()
        raise e


def update_SOMmodel_structure(Model_ID, object):
    try:
        connect.projSession.query(TbExperimentSOMModelsStructure).filter(
            TbExperimentSOMModelsStructure.Model_ID == Model_ID) \
            .update(object)
        connect.projSession.commit()
        connect.projSession.flush()
    except Exception as e:
        connect.projSession.rollback()
        raise e


def update_model_outputParas(add, delete, update):
    try:
        if len(add) != 0:
            for item in add:
                core_param = get_core_param(item['Parameter_Ecode'])
                if core_param is not None:
                    new_output = TbExperimentModelOutputParam(
                        Model_ID=item['Model_ID'],
                        Parameter_ID=core_param.Parameter_ID
                    )
                    connect.projSession.add(new_output)
                    item['Parameter_ID'] = core_param.Parameter_ID
                else:
                    new_core_parm = TbCoreParam(
                        Parameter_Ecode=item['Parameter_Ecode'],
                        Parameter_Name=item['Parameter_Name'],
                        Parameter_UOM_Name=item['Parameter_UOM_Name'],
                    )
                    connect.projSession.add(new_core_parm)
                    connect.projSession.commit()
                    new_output = TbExperimentModelOutputParam(
                        Model_ID=item['Model_ID'],
                        Parameter_ID=new_core_parm.Parameter_ID
                    )
                    connect.projSession.add(new_output)
                    item['Parameter_ID'] = new_core_parm.Parameter_ID
        if len(delete) != 0:
            for item in delete:
                connect.projSession.query(TbExperimentModelOutputParam) \
                    .filter_by(Model_ID=item['Model_ID'], Parameter_ID=item['Parameter_ID']) \
                    .delete(synchronize_session=False)
        if len(update) != 0:
            for item in update:
                connect.projSession.query(TbCoreParam).filter(TbCoreParam.Parameter_ID == item['Parameter_ID']) \
                    .update(item)
        connect.projSession.commit()
        connect.projSession.flush()
        return add
    except Exception as e:
        connect.projSession.rollback()
        raise e


def update_model_trainData(add, delete, update):
    try:
        if len(add) != 0:
            for item in add:
                if ('Core_ID' in item) and item['Core_ID'] != '':
                    new_train = TbExperimentModelTrainDatasets(
                        Model_ID=item['Model_ID'],
                        Core_ID=item['Core_ID']
                    )
                    connect.projSession.add(new_train)
                    item.pop('Model_ID')
                    update_core_dataList([], [], [item])

                else:
                    Model_ID = item['Model_ID']
                    item.pop('Model_ID')
                    # 新建岩芯
                    if ('Core_Name' not in item) or item['Core_Name'] == '':
                        newCore = TbRockCore(Core_Name='未命名')
                    else:
                        newCore = TbRockCore(Core_Name=item['Core_Name'])
                    connect.projSession.add(newCore)
                    connect.projSession.commit()
                    # 更新岩芯数据
                    item['Core_ID'] = newCore.Core_ID
                    update_core_dataList([], [], [item])
                    # 添加训练集
                    new_train = TbExperimentModelTrainDatasets(
                        Model_ID=Model_ID,
                        Core_ID=item['Core_ID']
                    )
                    item['Model_ID'] = Model_ID
                    connect.projSession.add(new_train)
        if len(delete) != 0:
            for item in delete:
                connect.projSession.query(TbExperimentModelTrainDatasets) \
                    .filter_by(Model_ID=item['Model_ID'], Core_ID=item['Core_ID']) \
                    .delete(synchronize_session=False)
        if len(update) != 0:
            update_core_dataList([], [], update)
        connect.projSession.commit()
        connect.projSession.flush()
        return add
    except Exception as e:
        connect.projSession.rollback()
        raise e


def update_model_testData(add, delete, update):
    try:
        if len(add) != 0:
            for item in add:
                if ('Core_ID' in item) and item['Core_ID'] != '':
                    new_test = TbExperimentTestDatasets(
                        Model_ID=item['Model_ID'],
                        Core_ID=item['Core_ID']
                    )
                    connect.projSession.add(new_test)
                    item.pop('Model_ID')
                    update_core_dataList([], [], [item])
                else:
                    Model_ID = item['Model_ID']
                    item.pop('Model_ID')
                    # 新建岩芯
                    if ('Core_Name' not in item) or item['Core_Name'] == '':
                        newCore = TbRockCore(Core_Name='未命名')
                    else:
                        newCore = TbRockCore(Core_Name=item['Core_Name'])
                    connect.projSession.add(newCore)
                    connect.projSession.commit()
                    # 更新岩芯数据
                    item['Core_ID'] = newCore.Core_ID
                    update_core_dataList([], [], [item])
                    # 添加测试集
                    new_test = TbExperimentTestDatasets(
                        Model_ID=Model_ID,
                        Core_ID=item['Core_ID']
                    )
                    item['Model_ID'] = Model_ID
                    connect.projSession.add(new_test)
        if len(delete) != 0:
            for item in delete:
                connect.projSession.query(TbExperimentTestDatasets) \
                    .filter_by(Model_ID=item['Model_ID'], Core_ID=item['Core_ID']) \
                    .delete(synchronize_session=False)
        if len(update) != 0:
            update_core_dataList([], [], update)
        connect.projSession.commit()
        connect.projSession.flush()
        return add
    except Exception as e:
        connect.projSession.rollback()
        raise e


def update_model_predictData(add, delete, update):
    try:
        if len(add) != 0:
            for item in add:
                if ('Core_ID' in item) and item['Core_ID'] != '':
                    # 岩芯存在
                    new_test = TbExperimentPredictDatasets(
                        Model_ID=str(item['Model_ID']),
                        Core_ID=item['Core_ID']
                    )
                    connect.projSession.add(new_test)
                    item.pop('Model_ID')
                    update_core_dataList([], [], [item])
                else:
                    Model_ID = str(item['Model_ID'])
                    item.pop('Model_ID')
                    # 新建岩芯
                    if ('Core_Name' not in item) or item['Core_Name'] == '':
                        newCore = TbRockCore(Core_Name='未命名')
                    else:
                        newCore = TbRockCore(Core_Name=item['Core_Name'])
                    connect.projSession.add(newCore)
                    connect.projSession.commit()
                    # 更新岩芯数据
                    item['Core_ID'] = newCore.Core_ID
                    update_core_dataList([], [], [item])
                    # 添加测试集
                    new_test = TbExperimentPredictDatasets(
                        Model_ID=Model_ID,
                        Core_ID=item['Core_ID']
                    )
                    item['Model_ID'] = Model_ID
                    connect.projSession.add(new_test)
        if len(delete) != 0:
            for item in delete:
                connect.projSession.query(TbExperimentPredictDatasets) \
                    .filter_by(Model_ID=str(item['Model_ID']), Core_ID=item['Core_ID']) \
                    .delete(synchronize_session=False)
        if len(update) != 0:
            update_core_dataList([], [], update)
        connect.projSession.commit()
        connect.projSession.flush()
        return add
    except Exception as e:
        connect.projSession.rollback()
        raise e


# 获取模型预测数据，不区分输入参数、输出参数
def get_model_data(model_id):
    model_id_str = str(model_id)
    results = connect.projSession.query(TbRockCore.Core_ID, TbRockCore.Core_Name, TbCoreParam.Parameter_Name,
                                        TbCoreParam.Parameter_Ecode, TbCoreData.Parameter_Value) \
        .join(TbExperimentPredictDatasets, TbExperimentPredictDatasets.Core_ID == TbRockCore.Core_ID) \
        .join(TbCoreData, TbCoreData.Core_ID == TbRockCore.Core_ID) \
        .join(TbCoreParam, TbCoreParam.Parameter_ID == TbCoreData.Parameter_ID) \
        .filter(TbExperimentPredictDatasets.Model_ID == model_id_str) \
        .filter(or_(
        TbCoreParam.Parameter_ID.in_(
            connect.projSession.query(TbExperimentModelInputParam.Parameter_ID)
            .filter(TbExperimentModelInputParam.Model_ID.in_(model_id))
        ),
        TbCoreParam.Parameter_ID.in_(
            connect.projSession.query(TbExperimentModelOutputParam.Parameter_ID)
            .filter(TbExperimentModelOutputParam.Model_ID.in_(model_id))
        )
    )) \
        .order_by(TbCoreParam.Parameter_ID, TbRockCore.Core_ID) \
        .all()
    # .join(TbExperimentModelOutputParam, TbExperimentModelOutputParam.Parameter_ID == TbCoreParam.Parameter_ID) \

    return results


# 获取模型样本训练数据(不区分输入参数、输出参数)
def get_model_SampleData(model_id):
    # 训练集
    train_sets = connect.projSession.query(TbRockCore.Core_ID, TbRockCore.Core_Name, TbCoreParam.Parameter_Name,
                                           TbCoreParam.Parameter_Ecode, TbCoreData.Parameter_Value) \
        .join(TbExperimentModelTrainDatasets, TbExperimentModelTrainDatasets.Core_ID == TbRockCore.Core_ID) \
        .join(TbCoreData, TbCoreData.Core_ID == TbRockCore.Core_ID) \
        .join(TbCoreParam, TbCoreParam.Parameter_ID == TbCoreData.Parameter_ID) \
        .filter(TbExperimentModelTrainDatasets.Model_ID == model_id) \
        .filter(or_(
        TbCoreParam.Parameter_ID.in_(
            connect.projSession.query(TbExperimentModelInputParam.Parameter_ID)
            .filter(TbExperimentModelInputParam.Model_ID == model_id)
        ),
        TbCoreParam.Parameter_ID.in_(
            connect.projSession.query(TbExperimentModelOutputParam.Parameter_ID)
            .filter(TbExperimentModelOutputParam.Model_ID == model_id)
        )
    )) \
        .order_by(TbCoreParam.Parameter_ID, TbRockCore.Core_ID) \
        .all()
    test_sets = connect.projSession.query(TbRockCore.Core_ID, TbRockCore.Core_Name, TbCoreParam.Parameter_Name,
                                          TbCoreParam.Parameter_Ecode, TbCoreData.Parameter_Value) \
        .join(TbExperimentTestDatasets, TbExperimentTestDatasets.Core_ID == TbRockCore.Core_ID) \
        .join(TbCoreData, TbCoreData.Core_ID == TbRockCore.Core_ID) \
        .join(TbCoreParam, TbCoreParam.Parameter_ID == TbCoreData.Parameter_ID) \
        .filter(TbExperimentTestDatasets.Model_ID == model_id) \
        .filter(or_(
        TbCoreParam.Parameter_ID.in_(
            connect.projSession.query(TbExperimentModelInputParam.Parameter_ID)
            .filter(TbExperimentModelInputParam.Model_ID == model_id)
        ),
        TbCoreParam.Parameter_ID.in_(
            connect.projSession.query(TbExperimentModelOutputParam.Parameter_ID)
            .filter(TbExperimentModelOutputParam.Model_ID == model_id)
        )
    )) \
        .order_by(TbCoreParam.Parameter_ID, TbRockCore.Core_ID) \
        .all()
    return objs_to_dict(train_sets), objs_to_dict(test_sets)


# 获取输入到模型的数据集数据（区分输入参数、输出参数）
def get_model_trainData(model_id):
    # 训练集
    train_sets_input = connect.projSession.query(TbRockCore.Core_ID, TbRockCore.Core_Name, TbCoreParam.Parameter_Name,
                                                 TbCoreParam.Parameter_Ecode, TbCoreData.Parameter_Value) \
        .join(TbExperimentModelTrainDatasets, TbExperimentModelTrainDatasets.Core_ID == TbRockCore.Core_ID) \
        .join(TbCoreData, TbCoreData.Core_ID == TbRockCore.Core_ID) \
        .join(TbCoreParam, TbCoreParam.Parameter_ID == TbCoreData.Parameter_ID) \
        .filter(TbExperimentModelTrainDatasets.Model_ID == model_id) \
        .filter(or_(
        TbCoreParam.Parameter_ID.in_(
            connect.projSession.query(TbExperimentModelInputParam.Parameter_ID)
            .filter(TbExperimentModelInputParam.Model_ID == model_id)
        )
    )) \
        .order_by(TbCoreParam.Parameter_ID, TbRockCore.Core_ID) \
        .all()
    train_sets_output = connect.projSession.query(TbRockCore.Core_ID, TbRockCore.Core_Name,
                                                  TbCoreParam.Parameter_Name,
                                                  TbCoreParam.Parameter_Ecode, TbCoreData.Parameter_Value) \
        .join(TbExperimentModelTrainDatasets, TbExperimentModelTrainDatasets.Core_ID == TbRockCore.Core_ID) \
        .join(TbCoreData, TbCoreData.Core_ID == TbRockCore.Core_ID) \
        .join(TbCoreParam, TbCoreParam.Parameter_ID == TbCoreData.Parameter_ID) \
        .filter(TbExperimentModelTrainDatasets.Model_ID == model_id) \
        .filter(or_(
        TbCoreParam.Parameter_ID.in_(
            connect.projSession.query(TbExperimentModelOutputParam.Parameter_ID)
            .filter(TbExperimentModelOutputParam.Model_ID == model_id)
        )
    )) \
        .order_by(TbCoreParam.Parameter_ID, TbRockCore.Core_ID) \
        .all()
    return objs_to_dict(train_sets_input), objs_to_dict(train_sets_output)


# 获取输入到模型的数据集数据（区分输入参数、输出参数）
def get_model_testData(model_id):
    # 训练集
    test_sets_input = connect.projSession.query(TbRockCore.Core_ID, TbRockCore.Core_Name, TbCoreParam.Parameter_Name,
                                                TbCoreParam.Parameter_Ecode, TbCoreData.Parameter_Value) \
        .join(TbExperimentTestDatasets, TbExperimentTestDatasets.Core_ID == TbRockCore.Core_ID) \
        .join(TbCoreData, TbCoreData.Core_ID == TbRockCore.Core_ID) \
        .join(TbCoreParam, TbCoreParam.Parameter_ID == TbCoreData.Parameter_ID) \
        .filter(TbExperimentTestDatasets.Model_ID == model_id) \
        .filter(or_(
        TbCoreParam.Parameter_ID.in_(
            connect.projSession.query(TbExperimentModelInputParam.Parameter_ID)
            .filter(TbExperimentModelInputParam.Model_ID == model_id)
        )
    )) \
        .order_by(TbCoreParam.Parameter_ID, TbRockCore.Core_ID) \
        .all()
    test_sets_output = connect.projSession.query(TbRockCore.Core_ID, TbRockCore.Core_Name,
                                                 TbCoreParam.Parameter_Name,
                                                 TbCoreParam.Parameter_Ecode, TbCoreData.Parameter_Value) \
        .join(TbExperimentTestDatasets, TbExperimentTestDatasets.Core_ID == TbRockCore.Core_ID) \
        .join(TbCoreData, TbCoreData.Core_ID == TbRockCore.Core_ID) \
        .join(TbCoreParam, TbCoreParam.Parameter_ID == TbCoreData.Parameter_ID) \
        .filter(TbExperimentTestDatasets.Model_ID == model_id) \
        .filter(or_(
        TbCoreParam.Parameter_ID.in_(
            connect.projSession.query(TbExperimentModelOutputParam.Parameter_ID)
            .filter(TbExperimentModelOutputParam.Model_ID == model_id)
        )
    )) \
        .order_by(TbCoreParam.Parameter_ID, TbRockCore.Core_ID) \
        .all()
    return objs_to_dict(test_sets_input), objs_to_dict(test_sets_output)


# 获取输入到模型的预测数据集数据（区分输入参数、输出参数）
def get_model_predictData(model_id):
    # 训练集
    predict_sets_input = connect.projSession.query(TbRockCore.Core_ID, TbRockCore.Core_Name, TbCoreParam.Parameter_Name,
                                                   TbCoreParam.Parameter_Ecode, TbCoreData.Parameter_Value) \
        .join(TbExperimentPredictDatasets, TbExperimentPredictDatasets.Core_ID == TbRockCore.Core_ID) \
        .join(TbCoreData, TbCoreData.Core_ID == TbRockCore.Core_ID) \
        .join(TbCoreParam, TbCoreParam.Parameter_ID == TbCoreData.Parameter_ID) \
        .filter(TbExperimentPredictDatasets.Model_ID == model_id) \
        .filter(or_(
        TbCoreParam.Parameter_ID.in_(
            connect.projSession.query(TbExperimentModelInputParam.Parameter_ID)
            .filter(TbExperimentModelInputParam.Model_ID == model_id)
        )
    )) \
        .order_by(TbCoreParam.Parameter_ID, TbRockCore.Core_ID) \
        .all()
    predict_sets_output = connect.projSession.query(TbRockCore.Core_ID, TbRockCore.Core_Name,
                                                    TbCoreParam.Parameter_Name,
                                                    TbCoreParam.Parameter_Ecode, TbCoreData.Parameter_Value) \
        .join(TbExperimentPredictDatasets, TbExperimentPredictDatasets.Core_ID == TbRockCore.Core_ID) \
        .join(TbCoreData, TbCoreData.Core_ID == TbRockCore.Core_ID) \
        .join(TbCoreParam, TbCoreParam.Parameter_ID == TbCoreData.Parameter_ID) \
        .filter(TbExperimentPredictDatasets.Model_ID == model_id) \
        .filter(or_(
        TbCoreParam.Parameter_ID.in_(
            connect.projSession.query(TbExperimentModelOutputParam.Parameter_ID)
            .filter(TbExperimentModelOutputParam.Model_ID == model_id)
        )
    )) \
        .order_by(TbCoreParam.Parameter_ID, TbRockCore.Core_ID) \
        .all()
    return objs_to_dict(predict_sets_input), objs_to_dict(predict_sets_output)


# 修改表tb_nn_model_stucture
def update_bpmodel_stucture(parm):
    try:
        connect.projSession.query(TbExperimentModelsStructure).filter(
            TbExperimentModelsStructure.Model_ID == parm['Model_ID']).update(parm)
        connect.projSession.commit()
    except Exception as e:
        print(e)


def get_bpmodel_structure(id):
    bpmodel_structure = connect.projSession.query(TbExperimentModelsStructure).filter(
        TbExperimentModelsStructure.Model_ID == id).first()
    return obj_to_dict(bpmodel_structure)


def get_sommodel_structure(id):
    som_model_structure = connect.projSession.query(TbExperimentSOMModelsStructure).filter(
        TbExperimentSOMModelsStructure.Model_ID == id).first()
    return obj_to_dict(som_model_structure)


def weight_refer_is_exist(filename):
    fileRecord = connect.projSession.query(TbExperimentModelsStructure).filter(
        TbExperimentModelsStructure.WeightFileName + ".pth" == filename).first()
    return fileRecord


def get_model_predictData(model_id):
    model_list = str(model_id)
    # 预测数据集
    predict_sets_input = connect.projSession.query(TbRockCore.Core_ID, TbRockCore.Core_Name,
                                                   TbCoreParam.Parameter_Name,
                                                   TbCoreParam.Parameter_Ecode, TbCoreData.Parameter_Value) \
        .join(TbExperimentPredictDatasets, TbExperimentPredictDatasets.Core_ID == TbRockCore.Core_ID) \
        .join(TbCoreData, TbCoreData.Core_ID == TbRockCore.Core_ID) \
        .join(TbCoreParam, TbCoreParam.Parameter_ID == TbCoreData.Parameter_ID) \
        .filter(TbExperimentPredictDatasets.Model_ID == model_list) \
        .filter(or_(
        TbCoreParam.Parameter_ID.in_(
            connect.projSession.query(TbExperimentModelInputParam.Parameter_ID)
            .filter(TbExperimentModelInputParam.Model_ID.in_(model_id))
        )
    )) \
        .order_by(TbCoreParam.Parameter_ID, TbRockCore.Core_ID) \
        .all()
    predict_sets_output = connect.projSession.query(TbRockCore.Core_ID, TbRockCore.Core_Name,
                                                    TbCoreParam.Parameter_Name,
                                                    TbCoreParam.Parameter_Ecode, TbCoreData.Parameter_Value) \
        .join(TbExperimentPredictDatasets, TbExperimentPredictDatasets.Core_ID == TbRockCore.Core_ID) \
        .join(TbCoreData, TbCoreData.Core_ID == TbRockCore.Core_ID) \
        .join(TbCoreParam, TbCoreParam.Parameter_ID == TbCoreData.Parameter_ID) \
        .filter(TbExperimentPredictDatasets.Model_ID == model_list) \
        .filter(or_(
        TbCoreParam.Parameter_ID.in_(
            connect.projSession.query(TbExperimentModelOutputParam.Parameter_ID)
            .filter(TbExperimentModelOutputParam.Model_ID.in_(model_id))
        )
    )) \
        .order_by(TbCoreParam.Parameter_ID, TbRockCore.Core_ID) \
        .all()
    return objs_to_dict(predict_sets_input), objs_to_dict(predict_sets_output)


def get_model_train_para(id):
    train_param = connect.projSession.query(TbExperimentModelsStructure).filter(
        TbExperimentModelsStructure.Model_ID == id).first()
    return train_param
